package wsz.rabbitmq.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import wsz.rabbitmq.utils.Constants;

import java.util.HashMap;
import java.util.Map;

/**
 * rabbitMq-队列配置
 * @author wsz
 * @date 2022/2/21 16:02
 **/
@Configuration
@EnableRabbit
@ComponentScan("wsz.rabbitmq")
public class RabbitConfig {

    /**
     路由模式direct
     待支付队列:
                   pay
        ex.pay  --------> queue.pay

     待支付死信队列
                     pay.dlx
        ex.pay.dlx  --------> queue.pay.dlx
     */

    /**
     * 未付款队列
     * @return
     */
    @Bean
    public Queue queue() {
        Map<String, Object> args = new HashMap<>();
        // 消息生存时间10s
        args.put("x-message-ttl", 10000);
        // 该队列关联的死信交换器
        args.put("x-dead-letter-exchange", "ex.pay.dlx");
        // 死信交换器的routingkey
        args.put("x-dead-letter-routing-key", "pay.dlx");

        // 队列
        return new Queue(Constants.PAY_QUEUEQ, true, false, false, args);
    }
    /**
     * 交换器
     * @return
     */
    @Bean
    public Exchange exchange() {
        return new DirectExchange(Constants.PAY_EXCHANGE, true, false, null);
    }
    /**
     * @return
     */
    @Bean
    public Binding binding() {
        return BindingBuilder.bind(queue()).to(exchange()).with(Constants.PAY_ROUTING_KEY).noargs();
    }

    /**
     * 死信队列
     * @return
     */
    @Bean
    public Queue queueDlx() {
        return new Queue(Constants.PAY_QUEUEQ_DLX, true, false, false, null);
    }

    /**
     * 死信交换器
     * @return
     */
    @Bean
    public Exchange exchangeDlx() {
        return new DirectExchange("ex.pay.dlx", true, false, null);
    }

    /**
     * 死信交换器绑定死信队列
     * @return
     */
    @Bean
    public Binding bindingDlx() {
        return BindingBuilder.bind(queueDlx()).to(exchangeDlx()).with("pay.dlx").noargs();
    }


    @Bean
    @Autowired
    public RabbitAdmin rabbitAdmin(ConnectionFactory factory) {
        return new RabbitAdmin(factory);
    }

    @Bean
    @Autowired
    public RabbitTemplate rabbitTemplate(ConnectionFactory factory) {
        return new RabbitTemplate(factory);
    }

    @Bean
    @Autowired
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();

        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }
}
